﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tilver.Configuration;
using System.Text.RegularExpressions;
using System.IO;
using Tilver.Configuration.Logging;

namespace Tilver.Common
{
    /// <summary>
    /// 日志文件输出处理类
    /// </summary>
    internal class FileAppender : IAppender
    {
        public FileAppenderElement Config { get; set; }
        private static Regex _regex = new Regex(@"{[\.\w]+}");
        private object _syncLock = new object();

        private string _filename;

        public FileAppender(FileAppenderElement config)
        {
            Config = config;
            _filename = GetFilename(config.FileName);
        }

        public void DoAppend(LogEntry entry)
        {
            string outStr = _regex.Replace(Config.Formatter, new MatchEvaluator(delegate(Match match)
            {
                string formatter = match.ToString().TrimStart('{').TrimEnd('}');
                return AppenderFormatter.GetValue(formatter, entry);
            }));
            lock (_syncLock)
            {
                using (StreamWriter writer = new StreamWriter(GetCustomName(), true, Encoding.UTF8))
                {
                    writer.Write(outStr);
                    writer.Flush();
                }
            }
        }
        private string GetCustomName()
        {
            return _regex.Replace(_filename, new MatchEvaluator((match) =>
            {
                return DateTime.Now.ToString(match.ToString().TrimStart('{').TrimEnd('}'));
            }));
        }
        private string GetFilename(string filename)
        {
            string ret = string.Empty;
            if (System.Web.HttpContext.Current != null)
            {
                ret = System.Web.HttpContext.Current.Server.MapPath(filename);
            }
            else
            {
                try
                {
                    ret = new Uri(filename).AbsolutePath;
                }
                catch
                {
                    ret = Path.Combine(Environment.CurrentDirectory, filename);
                }
            }
            return ret;
        }
    }
}
